package com.jieli.bt.att.ui.device

import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothProfile
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import com.jieli.bt.att.data.device.DeviceConnection
import com.jieli.bt.att.data.result.OpResult
import com.jieli.bt.att.tool.ble.BleManager
import com.jieli.bt.att.tool.ble.interfaces.IBtScanCallback
import com.jieli.bt.att.tool.ble.model.ScanDeviceInfo
import com.jieli.bt.att.tool.scan.BtScanner
import com.jieli.bt.att.ui.common.BluetoothViewModel
import com.jieli.bt.att.util.BluetoothUtil

/**
 * DeviceViewModel
 * @author zqjasonZhong
 * @since 2025/3/27
 * @email zhongzhuocheng@zh-jieli.com
 * @desc 设备界面实现逻辑
 */
class DeviceViewModel : BluetoothViewModel() {

    companion object {
        /**
         * 扫描设备操作
         */
        const val OP_SCAN_DEVICE = 0x01

        /**
         * 连接设备操作
         */
        const val OP_CONNECT_DEVICE = 0x02
    }

    private val btScanner = BtScanner.getInstance()

    val scanStateMLD = MutableLiveData<Boolean>()
    val foundDeviceMLD = MutableLiveData<ScanDeviceInfo>()
    val opResultMLD = MutableLiveData<OpResult<Any>>()

    private var connectingDevice: BluetoothDevice? = null

    private val connectionObserver = Observer<DeviceConnection> {
        if (BluetoothUtil.deviceEquals(connectingDevice, it.device)) {
            if (it.state != BluetoothProfile.STATE_CONNECTING) {
                connectingDevice = null
                if (it.state == BluetoothProfile.STATE_DISCONNECTING || it.state == BluetoothProfile.STATE_DISCONNECTED) {
                    opResultMLD.postValue(
                        OpResult(
                            OP_CONNECT_DEVICE,
                            OpResult.RES_FAILURE,
                            "Failed to connect device.",
                            it.device.address
                        )
                    )
                }
            }
        }
    }

    init {
        scanStateMLD.value = isScanning()
        deviceStateMLD.observeForever(connectionObserver)
    }

    override fun onCleared() {
        deviceStateMLD.removeObserver(connectionObserver)
        super.onCleared()
    }

    fun getConnectedDevices(): List<BluetoothDevice> = bleManager.connectedDeviceList

    fun isScanning(): Boolean = btScanner.isScanning

    fun startScan() {
        if (isScanning()) return
        btScanner.startScan(30 * 1000L, object : IBtScanCallback {
            override fun onAdapterChange(bEnabled: Boolean) {

            }

            override fun onDiscoveryState(bStart: Boolean) {
                scanStateMLD.value = bStart
            }

            override fun onDiscoveryDevice(scanDeviceInfo: ScanDeviceInfo?) {
                scanDeviceInfo?.let {
                    it.connection = getDeviceConnection(it.device)
                    foundDeviceMLD.value = it
                }
            }

            override fun onDiscoveryFail(code: Int, message: String?) {
                //搜索失败
                opResultMLD.postValue(
                    OpResult(OP_SCAN_DEVICE, code, message ?: "")
                )
            }
        })
    }

    fun stopScan() {
        btScanner.stopScan()
    }

    fun connectATTDevice(scanInfo: ScanDeviceInfo): Boolean {
        connectingDevice = scanInfo.device
        val ret = bleManager.connectBleDevice(scanInfo.device, BleManager.TRANSPORT_BREDR)
        if (!ret) {
            connectingDevice = null
            opResultMLD.postValue(
                OpResult(
                    OP_CONNECT_DEVICE,
                    OpResult.RES_FAILURE,
                    "Failed to connect device.",
                    scanInfo.device.address
                )
            )
        }
        return ret
    }

    fun disconnectDevice(device: BluetoothDevice?) {
        bleManager.disconnectBleDevice(device)
    }

}